home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / msdos / asmblit.asm next >
Assembly Source File  |  2000-02-10  |  7KB  |  299 lines

  1. ;
  2. ; Blitting routines for Mame, using MMX for stretching
  3. ; January/February 2000
  4. ; Bernd Wiebelt <bernardo@mame.net>
  5.  
  6. %assign SCANLINE_BRIGHTNESS 0            ; this can be 0%, 50% or 75% brightness
  7.  
  8. [BITS 32]
  9.  
  10. extern _palette_16bit_lookup            ; for 16 bit palettized mode
  11.                                         ; assuming entries are _doubled_
  12.                                         ; to their respective 32 bit values
  13.  
  14. [SECTION .data]
  15. halfbright15_mask:    dd 0x3def3def        ; mask for halfbright (4-4-4)
  16.                     dd 0x3def3def
  17. halfbright16_mask:    dd 0x7bef7bef        ; mask for halfbright (4-5-4)
  18.                     dd 0x7bef7bef
  19.  
  20.  
  21. [SECTION .text]
  22.  
  23. ; Here comes the generic template for blitting
  24. ; Note that the function names which are used by C are
  25. ; created on the fly by macro expansion. Cool feature.
  26.  
  27.  
  28. ; ******************************************
  29. ; function prototype
  30. ; void asmblit_Mx_Ny_Bsl_Xbpp[_palettized] (
  31. ;             int width, int height,
  32. ;            void* src, int src_offset,
  33. ;            void* dst, int dst_offset)
  34. ; ******************************************
  35.  
  36. ; list of parameters
  37. width        equ 8                        ; number of bitmap rows to copy
  38. height        equ 12                        ; number of bitmap dwords to copy
  39. src            equ 16                        ; source (memory bitmap)
  40. src_offset    equ 20                        ; offset to next bitmap row
  41. dst            equ 24                        ; destination (LINEAR framebuffer)
  42. dst_offset    equ 28                        ; offset to next framebuffer row
  43.  
  44.  
  45. ; *************************************************
  46. ; macro header for creation of custom blit function
  47. ; *************************************************
  48. %macro blit_template 4-5
  49.     GLOBAL _asmblit_%1x_%2y_%3sl_%4bpp%5
  50.     _asmblit_%1x_%2y_%3sl_%4bpp%5:
  51.  
  52. %assign MX  %1                        ; X-Stretch factor
  53. %assign MY  %2                        ; Y-Stretch factor
  54. %assign SL  %3                        ; emulate scanlines
  55. %assign BPP %4                        ; bits per pixel (16bpp or 8bpp)
  56.  
  57. ; decide wether palettized blit by the number of parameters passed
  58.  
  59. %if (%0 == 4)
  60.     %assign PALETTIZED 0
  61. %else
  62.     %assign PALETTIZED 1
  63. %endif
  64.  
  65. ; adjust parameters for 0, 50 or 75% scanlines
  66.  
  67. %if ((BPP == 16) && (SL == 1) && (SCANLINE_BRIGHTNESS > 0))
  68.     %assign SL 0
  69.     %assign REDUCED_SCANLINES 1
  70. %else
  71.     %assign REDUCED_SCANLINES 0
  72. %endif
  73.  
  74. ; ***************************
  75. ; generic function call intro
  76. ; ***************************
  77.  
  78. push ebp
  79. mov ebp, esp
  80.  
  81. ; **************************
  82. ; blit in chunks of 4 dwords
  83. ; **************************
  84.  
  85. add [ebp + width], DWORD 3
  86. shr    DWORD [ebp + width], 2
  87.  
  88.  
  89. %%next_line:
  90.  
  91. mov esi, [ebp + src]
  92. mov edi, [ebp + dst]
  93. mov ecx, [ebp + width]
  94.  
  95. align 16                                ; align the loop
  96.  
  97. %%next_linesegment:
  98.  
  99. ; ********************************
  100. ; load and process backbuffer data
  101. ; ********************************
  102.  
  103. %if (PALETTIZED == 1)                    ; stretch pixels palettized
  104.  
  105.     mov eax, 0
  106.     mov ebx, 0
  107.  
  108.     mov edx, [_palette_16bit_lookup]
  109.  
  110.     mov ax, [esi + 0]
  111.     mov bx, [esi + 2]
  112.     movd mm0, [edx+eax*4]
  113.     movd mm1, [edx+ebx*4]
  114.  
  115.     mov ax, [esi + 4]
  116.     mov bx, [esi + 6]
  117.     movd mm2, [edx+eax*4]
  118.     movd mm3, [edx+ebx*4]
  119.  
  120.     mov ax, [esi + 8]
  121.     mov bx, [esi + 10]
  122.     movd mm4, [edx+eax*4]
  123.     movd mm5, [edx+ebx*4]
  124.  
  125.     mov ax, [esi + 12]
  126.     mov bx, [esi + 14]
  127.     movd mm6, [edx+eax*4]
  128.     movd mm7, [edx+ebx*4]
  129.  
  130.     %if (MX == 1)                        ; now rearrange the stuff
  131.         punpcklwd mm0, mm1                ; add words to dwords
  132.         punpcklwd mm2, mm3
  133.         punpcklwd mm4, mm5
  134.         punpcklwd mm6, mm7
  135.  
  136.         punpckldq mm0, mm2                ; add dwords to quadwords
  137.         punpckldq mm4, mm6
  138.     %elif (MX == 2)
  139.         punpckldq mm0, mm1
  140.         punpckldq mm2, mm3
  141.         punpckldq mm4, mm5
  142.         punpckldq mm6, mm7
  143.     %endif
  144. %endif ; (PALETTIZED == 1)
  145.  
  146.  
  147. %if (PALETTIZED == 0)                    ; stretch pixel non-palettized
  148.  
  149.     movq mm0, [esi+0]                     ; always read 16 bytes at once
  150.     movq mm4, [esi+8]
  151.  
  152.     %if (MX >= 2)
  153.         movq mm2, mm0
  154.         movq mm6, mm4
  155.         %if (BPP == 8)
  156.             punpcklbw mm0, mm0
  157.             punpckhbw mm2, mm2
  158.             punpcklbw mm4, mm4
  159.             punpckhbw mm6, mm6
  160.         %elif (BPP = 16)
  161.             punpcklwd mm0, mm0
  162.             punpckhwd mm2, mm2
  163.             punpcklwd mm4, mm4
  164.             punpckhwd mm6, mm6
  165.         %endif
  166.     %endif
  167. %endif
  168.  
  169. ; *******************
  170. ; copy to framebuffer
  171. ; *******************
  172.  
  173. %if (MY > 1)
  174.     mov edx, [ebp + dst_offset]             ; only if y-stretching
  175. %endif
  176.  
  177. %if (MX == 1)
  178.     movq [fs:edi+0], mm0                    ; simply store the stuff back
  179.     movq [fs:edi+8], mm4
  180.     %if ((MY >= 2) && (SL = 0))
  181.         %if ((REDUCED_SCANLINES == 1) && (SCANLINE_BRIGHTNESS >= 50 ))
  182.             psrlq mm0, 1
  183.             psrlq mm4, 1
  184.             pand mm0, [halfbright16_mask]
  185.             pand mm4, [halfbright16_mask]
  186.             %if (SCANLINE_BRIGHTNESS >= 75)
  187.                 movq mm1, mm0
  188.                 movq mm5, mm4
  189.                 psrlq mm1, 1
  190.                 psrlq mm5, 1
  191.                 pand mm1, [halfbright16_mask]
  192.                 pand mm5, [halfbright16_mask]
  193.                 paddw mm0, mm1
  194.                 paddw mm4, mm5
  195.             %endif
  196.         %endif
  197.         movq [fs:edi+edx], mm0
  198.         movq [fs:edi+edx+8], mm4
  199.     %endif
  200. %endif
  201.  
  202. %if (MX >= 2)
  203.     movq [fs:edi], mm0
  204.     movq [fs:edi+8], mm2
  205.     movq [fs:edi+16], mm4
  206.     movq [fs:edi+24], mm6
  207.     %if ((MY >= 2) && (SL == 0))
  208.         %if ((REDUCED_SCANLINES == 1) && (SCANLINE_BRIGHTNESS >= 50))
  209.             psrlq mm0, 1
  210.             psrlq mm2, 1
  211.             psrlq mm4, 1
  212.             psrlq mm6, 1
  213.             pand mm0, [halfbright16_mask]
  214.             pand mm2, [halfbright16_mask]
  215.             pand mm4, [halfbright16_mask]
  216.             pand mm6, [halfbright16_mask]
  217.             %if (SCANLINE_BRIGHTNESS >= 75)
  218.                 movq mm1, mm0
  219.                 movq mm3, mm2
  220.                 movq mm5, mm4
  221.                 movq mm7, mm6
  222.                 psrlq mm1, 1
  223.                 psrlq mm3, 1
  224.                 psrlq mm5, 1
  225.                 psrlq mm7, 1
  226.                 pand mm1, [halfbright16_mask]
  227.                 pand mm3, [halfbright16_mask]
  228.                 pand mm5, [halfbright16_mask]
  229.                 pand mm7, [halfbright16_mask]
  230.                 paddw mm0, mm1
  231.                 paddw mm2, mm3
  232.                 paddw mm4, mm5
  233.                 paddw mm6, mm7
  234.             %endif
  235.         %endif
  236.         movq [fs:edi+edx], mm0
  237.         movq [fs:edi+edx+8], mm2
  238.         movq [fs:edi+edx+16], mm4
  239.         movq [fs:edi+edx+24], mm6
  240.     %endif
  241. %endif                                     ; end case (MX == 2)
  242.  
  243. ; ********************
  244. ; next iteration
  245. ; ********************
  246.  
  247.  
  248.     lea esi, [esi+16]                    ; next 16 src bytes
  249.     lea edi, [edi+(16*MX)]                ; next 16*MX dst bytes
  250.  
  251.     dec ecx
  252.     jnz NEAR %%next_linesegment            ; row done?
  253.  
  254.     mov eax, [ebp+src_offset]            ; next src row
  255.     add [ebp+src], eax
  256.  
  257.     mov eax, [ebp+dst_offset]            ; next dst row
  258.     imul eax, MY
  259.     add [ebp+dst], eax
  260.  
  261.     dec DWORD [ebp+height]                ;
  262.     jnz NEAR %%next_line                ; all rows done?
  263.  
  264.     mov esp, ebp                        ; yes, restore ebp
  265.     pop ebp
  266.     emms                                ; mmx cleanup [necessary?]
  267.     ret
  268.  
  269.  
  270. %endmacro
  271.  
  272. ;
  273. ; helper macro for creating the blitting functions
  274. ; argument 1: bpp, argument 2: palettized/empty
  275. ;
  276. %macro create_stretch 1-2
  277.     %assign i 1
  278.     %rep 4
  279.         %assign j 1
  280.         %rep 4
  281.             blit_template i,j,0,%1,%2    ; noscanline
  282.             blit_template i,j,1,%1,%2    ; scanline
  283.             %assign j j+1
  284.         %endrep
  285.     %assign i i+1
  286.     %endrep
  287. %endmacro
  288.  
  289.  
  290. ;
  291. ; create all blitting routines now
  292. ; this is all too easy...
  293. ;
  294. create_stretch 8
  295. create_stretch 16
  296. create_stretch 16,_palettized
  297.  
  298.  
  299.